import numpy as np
import matplotlib.pyplot as plt

# 找到f函数的最小值
f=lambda x,y:x**2+y**3-5*x*y

initT=100  # 初始温度
minT=1      # 温度下限
iterL=10000 # 每个温度的迭代次数
delta=0.99  # 温度衰减系数
k=1         # 波尔兹曼常数
# x的随机初始值
initX=10*np.random.rand()
initY=10*np.random.rand()
# 当前温度
nowT=initT
nowX=initX
nowY=initY
# 画图
fplot=[]
print("初始解：",initX,initY)
c=0
while nowT>minT:
    # 每个温度进行迭代
    for i in np.arange(1,iterL,1):
        # 当前函数值
        funVal=f(initX,initY)
        print(funVal)
        # 模拟分子的随机运动
        if np.random.random()>0.5:
            nowX=initX+(0.2*np.random.rand()-0.1)
        else:
            nowY = initY + (0.2 * np.random.rand()-0.1)
        # 在范围内
        if nowX>=0 and nowX <=10 and nowY>=0 and nowY<=10:
            # 分子运动后新的函数值
            funNew=f(nowX,nowY)
            # 更优则取
            if funNew>funVal:
                initX=nowX
                initY=nowY
            # 否则也有一定的概率取
            else:
                p=np.exp((funNew-funVal)/(k*nowT))
                #print(p)
                if np.random.rand()<p:
                    initX=nowX
                    initY=nowY

            fplot.append(funVal)
    # 温度下降
    nowT=nowT*delta

print("最优解：",initX,initY)
print("最优值：",f(initX,initY))
plt.scatter(np.arange(len(fplot)),fplot)
plt.show()
